package org.example.controller;

import lombok.extern.slf4j.Slf4j;
import org.example.service.LoanAllocationService;
import org.example.service.LoanAllocationService.LoanPlan;
import org.example.service.LoanAllocationService.MonthlyLoanAllocation;
import org.example.service.LoanAllocationService.OverdueData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 贷款分配控制器
 * 提供贷款分配计划生成和查询接口
 */
@Slf4j
@RestController
@RequestMapping("/loan/allocation")
public class LoanAllocationController {

    private static final Logger log = LoggerFactory.getLogger(LoanAllocationController.class);

    @Autowired
    private LoanAllocationService loanAllocationService;

    /**
     * 生成贷款分配计划
     */
    @GetMapping("/generate")
    public Map<String, Object> generatePlan() {
        log.info("开始生成贷款分配计划");

        LoanPlan plan = loanAllocationService.generateLoanPlan();

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "计划生成成功");
        result.put("totalLoans", plan.getTotalLoans());
        result.put("totalAmount", plan.getTotalAmount());
        result.put("startMonth", plan.getStartMonth().toString());
        result.put("endMonth", plan.getEndMonth().toString());
        result.put("monthlyCount", plan.getMonthlyAllocations().size());
        result.put("overdueRecordCount", plan.getOverdueDataList().size());

        return result;
    }

    /**
     * 获取每月放款明细
     */
    @GetMapping("/monthly")
    public Map<String, Object> getMonthlyAllocations() {
        log.info("获取每月放款明细");

        LoanPlan plan = loanAllocationService.generateLoanPlan();

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("data", plan.getMonthlyAllocations());
        result.put("total", plan.getMonthlyAllocations().size());

        return result;
    }

    /**
     * 获取指定月份的放款信息
     */
    @GetMapping("/monthly/{year}/{month}")
    public Map<String, Object> getMonthlyAllocation(
            @PathVariable Integer year,
            @PathVariable Integer month) {
        log.info("获取{}年{}月的放款信息", year, month);

        LoanPlan plan = loanAllocationService.generateLoanPlan();
        YearMonth targetMonth = YearMonth.of(year, month);

        MonthlyLoanAllocation allocation = plan.getMonthlyAllocations().stream()
            .filter(a -> a.getYearMonth().equals(targetMonth))
            .findFirst()
            .orElse(null);

        Map<String, Object> result = new HashMap<>();
        if (allocation != null) {
            result.put("success", true);
            result.put("data", allocation);
        } else {
            result.put("success", false);
            result.put("message", "未找到该月份的数据");
        }

        return result;
    }

    /**
     * 获取所有逾期数据
     */
    @GetMapping("/overdue")
    public Map<String, Object> getOverdueData() {
        log.info("获取所有逾期数据");

        LoanPlan plan = loanAllocationService.generateLoanPlan();

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("data", plan.getOverdueDataList());
        result.put("total", plan.getOverdueDataList().size());

        return result;
    }

    /**
     * 获取指定月份的逾期数据
     */
    @GetMapping("/overdue/{year}/{month}")
    public Map<String, Object> getOverdueDataForMonth(
            @PathVariable Integer year,
            @PathVariable Integer month) {
        log.info("获取{}年{}月的逾期数据", year, month);

        LoanPlan plan = loanAllocationService.generateLoanPlan();
        YearMonth targetMonth = YearMonth.of(year, month);

        List<OverdueData> overdueDataList = loanAllocationService.getOverdueDataForMonth(plan, targetMonth);

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("loanMonth", targetMonth.toString());
        result.put("data", overdueDataList);
        result.put("total", overdueDataList.size());

        return result;
    }

    /**
     * 导出每月放款明细为CSV
     */
    @GetMapping("/export/monthly")
    public void exportMonthlyAllocations(HttpServletResponse response) throws IOException {
        log.info("导出每月放款明细");

        LoanPlan plan = loanAllocationService.generateLoanPlan();
        String csv = loanAllocationService.exportMonthlyAllocationToCsv(plan);

        response.setContentType("text/csv");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition",
            "attachment; filename=monthly_allocations.csv");

        response.getOutputStream().write(csv.getBytes(StandardCharsets.UTF_8));
        response.getOutputStream().flush();
    }

    /**
     * 导出逾期数据为CSV
     */
    @GetMapping("/export/overdue")
    public void exportOverdueData(HttpServletResponse response) throws IOException {
        log.info("导出逾期数据");

        LoanPlan plan = loanAllocationService.generateLoanPlan();
        String csv = loanAllocationService.exportOverdueDataToCsv(plan);

        response.setContentType("text/csv");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition",
            "attachment; filename=overdue_data.csv");

        response.getOutputStream().write(csv.getBytes(StandardCharsets.UTF_8));
        response.getOutputStream().flush();
    }

    /**
     * 验证1-3月数据是否正常
     */
//    @GetMapping("/verify/jan-mar")
//    public Map<String, Object> verifyJanMarData() {
//        log.info("验证1-3月数据");
//
//        LoanPlan plan = loanAllocationService.generateLoanPlan();
//
//        Map<String, Object> result = new HashMap<>();
//        result.put("success", true);
//
//        // 提取所有1-3月的数据
//        List<Map<String, Object>> janMarData = new ArrayList<>();
//
//
//        for (MonthlyLoanAllocation allocation : plan.getMonthlyAllocations()) {
//            int month = allocation.getYearMonth().getMonthValue();
//            if (month >= 1 && month <= 3) {
//                Map<String, Object> monthData = new HashMap<>();
//                monthData.put("yearMonth", allocation.getYearMonth().toString());
//                monthData.put("month", month);
//                monthData.put("loanCount", allocation.getLoanCount());
//                monthData.put("loanAmount", allocation.getLoanAmount());
//                janMarData.add(monthData);
//            }
//        }
//
//        result.put("janMarMonths", janMarData);
//        result.put("total", janMarData.size());
//
//        // 按年份分组统计
//        Map<Integer, Map<String, Object>> yearlyStats = new HashMap<>();
//
//        for (MonthlyLoanAllocation allocation : plan.getMonthlyAllocations()) {
//            int month = allocation.getYearMonth().getMonthValue();
//            int year = allocation.getYearMonth().getYear();
//
//            if (month >= 1 && month <= 3) {
//                yearlyStats.putIfAbsent(year, new HashMap<>());
//                Map<String, Object> yearData = yearlyStats.get(year);
//
//                yearData.put("year", year);
//
//                switch (month) {
//                    case 1:
//                        yearData.put("jan", allocation.getLoanCount());
//                        break;
//                    case 2:
//                        yearData.put("feb", allocation.getLoanCount());
//                        break;
//                    case 3:
//                        yearData.put("mar", allocation.getLoanCount());
//                        break;
//                }
//            }
//        }
//
//        // 计算每年的总量和比例
//        for (Map<String, Object> yearData : yearlyStats.values()) {
//            int jan = (int) yearData.getOrDefault("jan", 0);
//            int feb = (int) yearData.getOrDefault("feb", 0);
//            int mar = (int) yearData.getOrDefault("mar", 0);
//            int total = jan + feb + mar;
//
//            yearData.put("total", total);
//            if (total > 0) {
//                yearData.put("janRatio", String.format("%.1f%%", jan * 100.0 / total));
//                yearData.put("febRatio", String.format("%.1f%%", feb * 100.0 / total));
//                yearData.put("marRatio", String.format("%.1f%%", mar * 100.0 / total));
//            }
//        }
//
//        result.put("yearlyStats", yearlyStats.values());
//
//        return result;
//    }

    /**
     * 获取计划统计信息
     */
    @GetMapping("/statistics")
    public Map<String, Object> getStatistics() {
        log.info("获取计划统计信息");

        LoanPlan plan = loanAllocationService.generateLoanPlan();

        // 计算统计数据
        int totalLoans = plan.getTotalLoans();
        int janLoans = plan.getMonthlyAllocations().stream()
            .filter(a -> a.getYearMonth().getMonthValue() == 1)
            .mapToInt(MonthlyLoanAllocation::getLoanCount)
            .sum();
        int febLoans = plan.getMonthlyAllocations().stream()
            .filter(a -> a.getYearMonth().getMonthValue() == 2)
            .mapToInt(MonthlyLoanAllocation::getLoanCount)
            .sum();
        int marLoans = plan.getMonthlyAllocations().stream()
            .filter(a -> a.getYearMonth().getMonthValue() == 3)
            .mapToInt(MonthlyLoanAllocation::getLoanCount)
            .sum();

        // 计算平均逾期率
        double avgOverdueRate = plan.getOverdueDataList().stream()
            .filter(OverdueData::isStable)
            .mapToDouble(OverdueData::getOverdueRate)
            .average()
            .orElse(0);

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("totalLoans", totalLoans);
        result.put("totalAmount", plan.getTotalAmount());
        result.put("totalMonths", plan.getMonthlyAllocations().size());
        result.put("januaryLoans", janLoans);
        result.put("februaryLoans", febLoans);
        result.put("marchLoans", marLoans);
        result.put("averageOverdueRate", String.format("%.2f%%", avgOverdueRate * 100));

        return result;
    }
}

